//深拷贝
function deeClone(origin, target){
  var tar = target || {},
      toStr = Object.prototype.toString,
      arrayType = '[object Object]';

  for(var k in origin){
    if(origin.hasOwnProperty(k)){
      if(typeof origin[k] === 'object' && origin[k] !== null){
        tar[k] = toStr.call(tar) === arrayType ? {} : [];
        deeClone(origin[k], tar[k]);
      }else{
        tar[k] = origin[k];
      }
    }
  }

  return tar;
}


// 获取滚动条滚动距离
function getScrollOffset(){
  if(window.pageXOffset){
    return{
      left: window.pageXOffset,
      top: window.pageYOffset
    }
  }else{
    return {
      left: document.body.scrollLeft + document.documentElement.scrollLeft,
      top: document.body.scrollTop + document.documentElement.scrollTop,
    }
  }
}

// 获取样式
function getStyle(obj, value){
  if(window.getComputedStyle){
    if(value){
      return parseInt(window.getComputedStyle(obj, null)[value]);
    }else{
      return parseInt(window.getComputedStyle(obj, null));
    }
  }else{
    if(value){
      return parseInt(obj.currentStyle[value]);
    }else{
      return parseInt(obj.currentStyle);
    }
    
  }
}

// 事件绑定
function addEvent(el, type, fn){
  if(el.addEventListener){
    el.addEventListener(type, fn, false);
  }else if(el.attachEvent){
    el.attachEvent('on' + type, function(){
      fn.call(el);
    });
  }else{
    el['on' + tyupe] = fn;
  }
}

// 取消事件绑定
function removeEvent(el, type, fn){
  if(el.addEventListener){
    el.removeEventListener(type, fn, false);
  }else if(el.attachEvent){
    el.detachEvent('on' + type, fn)
  }else{
    el['on' + el] = null;
  }
}

// 阻止冒泡
function cancelBubble(e){
  var e = e || window.event;
  if(e.stopPropagation){
    e.stopPropagation()
  }else{
    e.cancelBubble = true;
  }
}

// 阻止默认事件
function preventDefaultEvent(e){
  var e = e || window.event;
  if(e.preventDefault){
    e.preventDefault();
  }else{
    e.returnValue = false;
  }
}


// 拖拽
function elemDrag(elem) {
  var x, y;
  addEvent(elem, 'mousedown', function (e) {
    var e = e || windwo.event;

    x = pagePos(e).X - getStyle(elem, 'left');
    y = pagePos(e).Y - getStyle(elem, "top");

    addEvent(document, 'mousemove', mouseMove);
    addEvent(document, 'mouseup', mouseUp);
  });

  function mouseMove(e) {
    var e = e || window.event,
      oLeft = pagePos(e).X - x,
      oTop = pagePos(e).Y - y,
      wWidth = window.innerWidth,
      wHeihgt = window.innerHeight,
      tWidth = getStyle(elem, 'width');
    tHeight = getStyle(elem, 'height');
    // elem.style.left = pagePos(e).X + 'px';
    // elem.style.top = pagePos(e).Y + 'px';
    if (oLeft < 0 && oTop < 0) {
      oLeft = 0;
      oTop = 0;
    } else if (oLeft + tWidth > wWidth && oTop + tHeight > wHeihgt) {
      oLeft = wWidth - tWidth;
      oTop = wHeihgt - tHeight;
    } else if (oTop < 0 && oLeft + tWidth > wWidth) {
      oTop = 0;
      oLeft = wWidth - tWidth;
    } else if (oLeft < 0 && oTop + tHeight > wHeihgt) {
      oLeft = 0;
      oTop = wHeihgt - tHeight;
    } else if (oTop < 0) {
      oTop = 0;
    } else if (oLeft < 0) {
      oLeft = 0;
    } else if (oLeft + tWidth > wWidth) {
      oLeft = wWidth - tWidth;
    } else if (oTop + tHeight > wHeihgt) {
      oTop = wHeihgt - tHeight;
    }
    elem.style.left = oLeft + 'px';
    elem.style.top = oTop + 'px';

    cancelBubble(e);
    preventDefaultEvent(e);
  }

  function mouseUp(e) {
    var e = e || window.event;
    removeEvent(document, 'mousemove', mouseMove);
    removeEvent(document, 'mouseUp', mouseUp);
  }
};


// myforEach 循环执行所提供的函数一遍
;Array.prototype.myforEach = function(fn){
  var arr = this,
      len = this.length,
      arg2 = arguments[1] || window;
  
  for(var i = 0; i < len; i++){
    fn.apply(arg2, p[arr[i], i, arr]);
  }
}

// myfilter 过滤器 循环执行所提供的函数将符合条件的汇总返回
;Array.prototype.myfilter = function(fn){
  var arr = this,
      len = this.length,
      arg2 = arguments[1] || window,
      newarr = [],
      item;

  for(var i = 0; i < len; i++){
    item = deeClone(arr[i]);
    newarr.push(fn.apply(arg2, [arr[i], i, arr]) ? item : '');
  }

  return newarr;
}

// mymap 循环执行所提供的函数的结果汇总返回
Array.prototype.mymap = function(fn){
  var arr = this,
      len = this.length,
      arg2 = arguments[1] || window,
      newarr = [],
      item;

  for(var i = 0; i < len; i++){
    item = deeClone(arr[i]);
    newarr.push(fn.apply(arg2, [arr[i], i, arr]));
  }

  return newarr
}


//重写every 遍历到return条件不符合为止
Array.prototype.myevery = function(fn){
  var arr = this,
      len = arr.length,
      arg2 = arguments[1] || window,
      res = true;
  for(var i = 0; i < len; i++){
    if(!(fn.apply(arg2, [arr[i], i, arr]))){
      res = false;
      break;
    }
  }
  return res;
}

// 重写some 遍历到return条件符合为止
Array.prototype.mysome = function(fn){
  var arr = this,
      len = arr.length,
      arg2 = arguments[1] || window,
      res = false;
  
  for(var i = 0; i < len; i++){
    if(fn.apply(arg2, [arr[i], i, arr])){
      res = true;
      break;
    }
  }

  return res;
}

// 重写 reduce 
Array.prototype.myreduce = function(fn, initaValue){
  var arr = this,
      len = arr.length,
      arg2 = arguments[2] || window;
  
  for(var i = 0; i < len; i++){
    initaValue = fn.apply(arg2, (initaValue, arr[i], i, arr));
  }

  return initaValue;
}

// 重写 reduceRight
Array.prototype.mymyreduceRight = function(fn, iniaValue){
  var arr = this,
      len = arr.length - 1,
      arg2 = arguments[2] || window;
  
  for(var i = len; i > 0; i--){
    initaValue = fn.apply(arg2, [iniaValue, arr[i], i, arr]);
  }
  return iniaValue;
}


// 重写getElementsByClassName
Document.prototype.getElementsByClassName = 
Element.prototype.getElementsByClassName = 
function(className){
  var nodeArr = document.getElementsByTagName("*"),
      nodeArrLen = nodeArr.length,
      nodeItem,
      classArr = [];
  
  for(var i = 0; i < nodeArrLen; i++){
    nodeItem = nodeArr[i];
    nodeItem.className.indexOf(className) >= 0 ? 
                       classArr.push(nodeItem) : '';
  }
  return classArr;
}


// 迭代器
function makeIterator(array){
  var nextIndex = 0;
  return {
    next: function(){
      return nextIndex < array.length ? {value: array[nextIndex++], done: false}:{value: undefined, done: true};
    }
  }
}



// myIS
Object.myIS = function(a, b){
  if(a === b){
    return a !== 0 || 1 / a === 1 / b;
  }

  return a !== a || b !== b; 
}



